home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / session.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-27  |  10.0 KB  |  490 lines

  1. /* NOS User Session control
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by PA0GRI
  5.  */
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "config.h"
  9. #include "mbuf.h"
  10. #include "proc.h"
  11. #include "ftpcli.h"
  12. #include "icmp.h"
  13. #include "telnet.h"
  14. #include "tty.h"
  15. #include "session.h"
  16. #include "hardware.h"
  17. #include "socket.h"
  18. #include "cmdparse.h"
  19. #include "rlogin.h"
  20. #include "commands.h"
  21. #include "main.h"
  22. #include "dirutil.h"
  23.  
  24. struct session *Sessions;
  25. struct session *Command;
  26. struct session *Current;
  27. struct session *Lastcurr;
  28. extern unsigned char SCREENlength;
  29. int Row;
  30. int Morewait;
  31.  
  32. char Notval[] = "Not a valid control block\n";
  33. static char Badsess[] = "Invalid session\n";
  34. char TooManySessions[] = "Too many sessions\n";
  35.  
  36. char *Sestypes[] = {
  37.     "", /* The command session */
  38.     "Telnet",
  39.     "FTP",
  40.     "AX25",
  41.     "Finger",
  42.     "Ping",
  43.     "NET/ROM",
  44.     "Command",
  45.     "More",
  46.     "Hopcheck",
  47.     "Tip",
  48.     "PPP PAP",
  49.     "Dial",
  50.     "Query",
  51.     "Cache",
  52.     "Rlogin",
  53.     "",        /* The trace session */
  54.     "View",
  55.     "Script"
  56. };
  57.  
  58. /* Convert a character string containing a decimal session index number
  59.  * into a pointer. If the arg is NULLCHAR, use the current default session.
  60.  * If the index is out of range or unused, return NULLSESSION.
  61.  */
  62. struct session *
  63. sessptr(cp)
  64. char *cp;
  65. {
  66.     register struct session *sp;
  67.     unsigned int i;
  68.  
  69.     if(cp == NULLCHAR){
  70.         sp = Lastcurr;
  71.     } else {
  72.         i = (unsigned)atoi(cp);
  73.         if(i >= Nsessions)
  74.             sp = NULLSESSION;
  75.         else
  76.             sp = &Sessions[i];
  77.     }
  78.     if(sp == NULLSESSION || sp->type == FREE)
  79.         sp = NULLSESSION;
  80.  
  81.     return sp;
  82. }
  83.  
  84. /* Select and display sessions */
  85. int
  86. dosession(argc,argv,p)
  87. int argc;
  88. char *argv[];
  89. void *p;
  90. {
  91.     struct session *sp;
  92.     struct sockaddr fsocket;
  93.     int i,k,s;
  94.     int r,t;
  95.     char *cp;
  96.     char *param[3];
  97.  
  98.     sp = (struct session *)p;
  99.  
  100.     if(argc > 1){
  101.         if((sp = sessptr(argv[1])) == NULLSESSION){
  102.             tprintf("Session %s not active\n",argv[1]);
  103.             return 1;
  104.         }
  105.         if(argc == 2){
  106.             go(0,NULL,sp);
  107.         }
  108.         param[0] = argv[2];
  109.         param[1] = argv[3];
  110.         param[2] = NULL;
  111.         if(argc > 2){
  112.             switch (*argv[2]) {
  113.             case 'f':    /* flowmode */
  114.                 setbool(&sp->flowmode,"Set flowmode on/off",argc-2,param);
  115.                 break;
  116.             default:
  117.                 tprintf("usage:session # [flow [on/off]]\n");
  118.             }
  119.         }
  120.         return 0;
  121.     }
  122.     tprintf(" #  S#  Type     Rcv-Q Snd-Q State        Remote socket\n");
  123.     for(sp=Sessions; sp < &Sessions[Nsessions];sp++){
  124.         if(sp->type == FREE || sp->type == COMMAND || \
  125.            sp->type == TRACESESSION)
  126.             continue;
  127.  
  128.         /* Rcv-Q includes output pending at the screen driver */
  129.         r = socklen(sp->output,1);
  130.         t = 0;
  131.         cp = NULLCHAR;
  132.         if((s = sp->s) != -1){
  133.             i = SOCKSIZE;
  134.             s = sp->s;
  135.             k = getpeername(s,(char *)&fsocket,&i);
  136.             r += socklen(s,0);
  137.             t += socklen(s,1);
  138.             cp = sockstate(s);
  139.         }
  140.         tprintf("%c", (Lastcurr == sp)? '*':' ');
  141.         tprintf("%-3u", (unsigned)(sp - Sessions));
  142.         tprintf("%-4d%-8s%6d%6d %-13s",
  143.          s,
  144.          Sestypes[sp->type],
  145.          r,
  146.          t,
  147.          (cp != NULLCHAR) ? cp : "Limbo!");
  148.         if(sp->name != NULLCHAR)
  149.             tprintf("%s ",sp->name);
  150.         if(sp->s != -1 && k == 0)
  151.             tprintf("(%s)",psocket(&fsocket));
  152.  
  153.         tprintf("\n");
  154.         if(sp->type == FTP && (s = sp->cb.ftp->data) != -1){
  155.             /* Display data channel, if any */
  156.             i = SOCKSIZE;
  157.             k = getpeername(s,(char *)&fsocket,&i);
  158.             r = socklen(s,0);
  159.             t = socklen(s,1);
  160.             cp = sockstate(s);
  161.             tprintf("    %-4d%-8s%6d%6d %-13s%s",
  162.              s,
  163.              Sestypes[sp->type],
  164.              r,
  165.              t,
  166.              (cp != NULLCHAR) ? cp : "Limbo!",
  167.              (sp->name != NULLCHAR) ? sp->name : "");
  168.             if(k == 0)
  169.                 tprintf(" (%s)",psocket(&fsocket));
  170.             if(tprintf("\n") == EOF)
  171.                 break;
  172.         }
  173.         if(sp->rfile != NULLCHAR)
  174.             tprintf("    Record: %s\n",sp->rfile);
  175.         if(sp->ufile != NULLCHAR)
  176.             tprintf("    Upload: %s\n",sp->ufile);
  177.     }
  178.     return 0;
  179. }
  180. /* Resume current session, and wait for it */
  181. int
  182. go(argc,argv,p)
  183. int argc;
  184. char *argv[];
  185. void *p;
  186. {
  187.     struct session *sp;
  188.  
  189.     sp = (struct session *)p;
  190.     if(sp == NULLSESSION || sp->type == FREE || \
  191.        sp->type == COMMAND || sp->type == TRACESESSION)
  192.         return 0;
  193.     Current = sp;
  194.     swapscreen(Command,sp);
  195.     psignal(sp,0);
  196.     return 0;
  197. }
  198. int
  199. doclose(argc,argv,p)
  200. int argc;
  201. char *argv[];
  202. void *p;
  203. {
  204.     struct session *sp;
  205.  
  206.     sp = (struct session *)p;
  207.     if(argc > 1)
  208.         sp = sessptr(argv[1]);
  209.  
  210.     if(sp == NULLSESSION){
  211.         tprintf(Badsess);
  212.         return -1;
  213.     }
  214.     shutdown(sp->s,1);
  215.     return 0;
  216. }
  217. int
  218. doreset(argc,argv,p)
  219. int argc;
  220. char *argv[];
  221. void *p;
  222. {
  223.     struct session *sp;
  224.  
  225.     sp = (struct session *)p;
  226.     if(argc > 1)
  227.         sp = sessptr(argv[1]);
  228.  
  229.     if(sp == NULLSESSION){
  230.         tprintf(Badsess);
  231.         return -1;
  232.     }
  233.     /* Unwedge anyone waiting for a domain resolution, etc */
  234.     alert(sp->proc,EABORT);
  235.     shutdown(sp->s,2);
  236.     if(sp->type == FTP)
  237.         shutdown(sp->cb.ftp->data,2);
  238.     return 0;
  239. }
  240. int
  241. dokick(argc,argv,p)
  242. int argc;
  243. char *argv[];
  244. void *p;
  245. {
  246.     struct session *sp;
  247.  
  248.     sp = (struct session *)p;
  249.     if(argc > 1)
  250.         sp = sessptr(argv[1]);
  251.  
  252.     if(sp == NULLSESSION){
  253.         tprintf(Badsess);
  254.         return -1;
  255.     }
  256.     sockkick(sp->s);
  257.     if(sp->type == FTP)
  258.         sockkick(sp->cb.ftp->data);
  259.     return 0;
  260. }
  261.  
  262. struct session *
  263. newsession(name,type,split)
  264. char *name;
  265. int type;
  266. int split;
  267. {
  268.     register struct session *sp;
  269.     int i;
  270.  
  271.     /* Reserve the highest session for Trace, so that
  272.      * the F-key session switching works correctly - WG7J
  273.      */
  274.     if(type == TRACESESSION) { /* This can only get called once !! */
  275.         i=0;
  276.         sp=Sessions;
  277.         while(i!=Nsessions-1) {
  278.             i++;
  279.             sp++;
  280.         }
  281.     } else {
  282.         for(i=0,sp=Sessions;i < Nsessions;sp++,i++)
  283.             if(sp->type == FREE)
  284.                 break;
  285.     }
  286.     if(i == Nsessions)
  287.         return NULLSESSION;
  288.  
  289.     sp->type = type;
  290.     sp->s = -1;
  291.     if(name != NULLCHAR)
  292.         sp->name = strdup(name);
  293.     else
  294.         sp->name = NULLCHAR;
  295.     sp->proc = Curproc;
  296.     /* Create standard input and output sockets. Output is
  297.      * translated to local end-of-line by default
  298.      */
  299.     Curproc->input =  sp->input = socket(AF_LOCAL,SOCK_STREAM,0);
  300.     seteol(Curproc->input,Eol);
  301.     sockmode(Curproc->input,SOCK_BINARY);
  302.     Curproc->output = sp->output = socket(AF_LOCAL,SOCK_STREAM,0);
  303.     seteol(Curproc->output,Eol);
  304.     sockmode(Curproc->output,SOCK_ASCII);
  305.  
  306.     /* on by default */
  307.     sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
  308.     sp->flowmode = 0;    /* Off by default */
  309. /*    sp->row = MOREROWS;    */
  310.     sp->row = SCREENlength - 1 - (split * 2);
  311.     sp->morewait = 0;
  312.     sp->split = split;
  313.     newscreen(sp);
  314.     swapscreen(Current,sp);
  315.     Current = sp;
  316.     return sp;
  317. }
  318. void
  319. freesession(sp)
  320. struct session *sp;
  321. {
  322.     if(sp == NULLSESSION)
  323.         return;
  324.     pwait(NULL);    /* Wait for any pending output to go */
  325.     rflush();
  326.  
  327.     if(sp->proc1 != NULLPROC)
  328.         killproc(sp->proc1);
  329.     sp->proc1 = NULLPROC;
  330.     if(sp->proc2 != NULLPROC)
  331.         killproc(sp->proc2);
  332.     sp->proc2 = NULLPROC;
  333.  
  334.     free_p(sp->ttystate.line);
  335.     sp->ttystate.line = NULLBUF;
  336.     if(sp->s != -1)
  337.         close_s(sp->s);
  338.     if(sp->record != NULLFILE){
  339.         fclose(sp->record);
  340.         sp->record = NULLFILE;
  341.     }
  342.     free(sp->rfile);
  343.     sp->rfile = NULLCHAR;
  344.     if(sp->upload != NULLFILE){
  345.         fclose(sp->upload);
  346.         sp->upload = NULLFILE;
  347.     }
  348.     free(sp->ufile);
  349.     sp->ufile = NULLCHAR;
  350.     free(sp->name);
  351.     sp->name = NULLCHAR;
  352.     sp->type = FREE;
  353.  
  354.     close_s(sp->input);
  355.     sp->input = -1;
  356.     sp->proc->input = -1;
  357.     close_s(sp->output);
  358.     sp->output = -1;
  359.     sp->proc->output = -1;
  360.  
  361.     freescreen(sp);
  362.     if(Current == sp){
  363.         Current = Command;
  364.         swapscreen(NULLSESSION,Command);
  365.         alert(Display,1);
  366.     }
  367.     if(Lastcurr == sp)
  368.         Lastcurr = NULLSESSION;
  369. }
  370. #ifdef ALLCMD
  371. /* Control session recording */
  372. int
  373. dorecord(argc,argv,p)
  374. int argc;
  375. char *argv[];
  376. void *p;
  377. {
  378. struct session *sp;
  379. char *mode;
  380. char fname[128];
  381.  
  382.     sp = (struct session *)p;
  383.     if(sp == NULLSESSION){
  384.         tprintf("No current session\n");
  385.         return 1;
  386.     }
  387.     if(argc > 1){
  388.         if(sp->rfile != NULLCHAR){
  389.             fclose(sp->record);
  390.             free(sp->rfile);
  391.             sp->record = NULLFILE;
  392.             sp->rfile = NULLCHAR;
  393.         }
  394.         /* Open new record file, unless file name is "off", which means
  395.          * disable recording
  396.          */
  397.         if(strcmp(argv[1],"off") != 0){
  398.             if(sockmode(sp->output,-1) == SOCK_ASCII)
  399.                 mode = APPEND_TEXT;
  400.             else
  401.                 mode = APPEND_BINARY;
  402.  
  403.             strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
  404.             if((sp->record = fopen(fname,mode)) == NULLFILE)
  405.                 tprintf("Can't open %s: %s\n",fname,sys_errlist[errno]);
  406.             else
  407.                 sp->rfile = strdup(fname);
  408.         }
  409.     }
  410.     if(sp->rfile != NULLCHAR)
  411.         tprintf("Recording into %s\n",sp->rfile);
  412.     else
  413.         tprintf("Recording off\n");
  414.     return 0;
  415. }
  416. /* Control file transmission */
  417. int
  418. doupload(argc,argv,p)
  419. int argc;
  420. char *argv[];
  421. void *p;
  422. {
  423. register struct session *sp;
  424. char fname[128];
  425.  
  426.     sp = (struct session *)p;
  427.     if(sp == NULLSESSION){
  428.         tprintf("No current session\n");
  429.         return 1;
  430.     }
  431.     if(argc < 2){
  432.         if(sp->ufile != NULLCHAR)
  433.             tprintf("Uploading %s\n",sp->ufile);
  434.         else
  435.             tprintf("Uploading off\n");
  436.         return 0;
  437.     }
  438.     if(strcmp(argv[1],"stop") == 0 && sp->upload != NULLFILE){
  439.         /* Abort upload */
  440.         fclose(sp->upload);
  441.         sp->upload = NULLFILE;
  442.         free(sp->ufile);
  443.         sp->ufile = NULLCHAR;
  444.         killproc(sp->proc2);
  445.         sp->proc2 = NULLPROC;
  446.         return 0;
  447.     }
  448.     /* Open upload file */
  449.     strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
  450.     if((sp->upload = fopen(fname,READ_TEXT)) == NULLFILE){
  451.         tprintf("Can't read %s: %s\n",fname,sys_errlist[errno]);
  452.         return 1;
  453.     }
  454.     sp->ufile = strdup(fname);
  455.     /* All set, invoke the upload process */
  456.     sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
  457.     return 0;
  458. }
  459. /* File uploading task */
  460. void
  461. upload(unused,sp1,p)
  462. int unused;
  463. void *sp1;
  464. void *p;
  465. {
  466.     struct session *sp;
  467.     int oldf;
  468.     char *buf;
  469.  
  470.     sp = (struct session *)sp1;
  471.  
  472.     /* Disable newline buffering for the duration */
  473.     oldf = setflush(sp->s,-1);
  474.  
  475.     buf = mallocw(BUFSIZ);
  476.     while(fgets(buf,BUFSIZ,sp->upload) != NULLCHAR)
  477.         if(usputs(sp->s,buf) == EOF)
  478.             break;
  479.  
  480.     free(buf);
  481.     usflush(sp->s);
  482.     setflush(sp->s,oldf);
  483.     fclose(sp->upload);
  484.     sp->upload = NULLFILE;
  485.     free(sp->ufile);
  486.     sp->ufile = NULLCHAR;
  487.     sp->proc2 = NULLPROC;
  488. }
  489. #endif /*ALLCMD*/
  490.